package info.motteke.mybws.node;

import info.motteke.mybws.AbstractNodeVisitor;
import info.motteke.mybws.Node;
import info.motteke.mybws.utils.IndentablePrintWriter;

import java.io.StringWriter;

public class ToStringVisitor extends AbstractNodeVisitor {

    private final StringWriter buf;

    private final IndentablePrintWriter pw;

    public ToStringVisitor(boolean prettyPrint) {
        buf = new StringWriter();

        String indent;
        String lineSeparator;

        if (prettyPrint) {
            indent = "  ";
            lineSeparator = "\n";
        } else {
            indent = "";
            lineSeparator = "";
        }

        pw = new IndentablePrintWriter(buf, indent, lineSeparator);
    }

    @Override
    public void visitExcel(ExcelNode excel) {
        pw.indent();
        pw.println("excel [");

        visitChildren(excel);

        pw.indent();
        pw.println("]");
    }

    @Override
    public void visitSheet(SheetNode sheet) {
        pw.indent();
        pw.print("sheet(");
        pw.print(sheet.getName());
        pw.println(") [");

        visitChildren(sheet);

        pw.indent();
        pw.println("]");
    }

    @Override
    public void visitIteration(IterationNode iteration) {
        pw.indent();
        pw.print("iterate(list=");
        pw.print(iteration.getList());
        pw.println(") [");

        visitChildren(iteration);

        pw.indent();
        pw.println("]");
    }

    @Override
    public void visitCell(CellNode cell) {
        pw.indent();
        pw.print("cell(");
        pw.print(cell.getPosition());
        pw.println(") [");

        visitChildren(cell);

        pw.indent();
        pw.println("]");
    }

    @Override
    public void visitText(TextNode text) {
        pw.indent();
        pw.println(text.getText());
    }

    @Override
    protected void visitChildren(Node node) {
        pw.increaseIndent();
        super.visitChildren(node);
        pw.decreaseIndent();
    }

    @Override
    public String toString() {
        pw.close();
        return buf.toString();
    }
}
